
#include "GLline.h"

bool GLline::GetClosestPoint( const GLvec3f& pt,GLvec3f& ptClosest)
{
	GLvec3f v;

	bool bProjected = GetProjectPoint( pt,v);

	if( bProjected )
	{
		ptClosest = v;
		return bProjected;
	}
	

	GLvec3f ab = m_B - m_A;
	GLvec3f ax = pt - m_A;	
	if( ax.DotProd( ab ) <0.f )
	{
		ptClosest = m_A;
		return bProjected;
	}

	GLvec3f bx = pt - m_B;
	GLvec3f ba = m_A - m_B;
	if( bx.DotProd( ba ) <0.f )
	{
		ptClosest = m_B;
		return bProjected;
	}

	return bProjected;
}

bool GLline::GetProjectPoint( const GLvec3f& pt,GLvec3f& ptCast)
{
	GLvec3f ab = m_B - m_A;
	GLvec3f ax = pt - m_A;	
	if( ax.DotProd( ab ) <0.f )
		return false;

	GLvec3f bx = pt - m_B;
	GLvec3f ba = m_A - m_B;
	if( bx.DotProd( ba ) <0.f )
		return false;

	ab.Normalize();
	ab.Scale( ax.DotProd( ab ));
	ptCast = m_A + ab;

	return true;
}

bool GLline::PtProjectLine( const GLvec3f& pt ) const
{
	GLvec3f ab = m_B - m_A;
	GLvec3f ax = pt - m_A;	
	if( ax.DotProd( ab ) <0.f )
		return false;

	GLvec3f bx = pt - m_B;
	GLvec3f ba = m_A - m_B;
	if( bx.DotProd( ba ) <0.f )
		return false;

	return true;
}

float GLline::Length()
{
	GLvec3f ab = m_B - m_A;
	return ab.Length();
}

GLvec3f GLline::DirectionAB()
{
	GLvec3f ab = m_B - m_A;
	ab.Normalize();
	return ab;
}

GLvec3f GLline::DirectionBA()
{
	GLvec3f ba = m_A - m_B;
	ba.Normalize();
	return ba;
}

bool GLline::PtOnLine( const GLvec3f& pt,float epsilon) const
{
	GLvec3f ab = m_B - m_A;
	GLvec3f ax = pt - m_A;		

	ab.Normalize();
	ab.Scale( ax.DotProd( ab ) );
	
	GLvec3f c = m_A + ab;

	if( pt.Distance(c) > epsilon )
		return false;

	return true;
}

bool GLline::PtInLine( const GLvec3f& pt,float epsilon) const
{
	GLvec3f ab = m_B - m_A;
	GLvec3f ax = pt - m_A;		
	if( ax.DotProd( ab ) <0.f )
		return false;

	GLvec3f bx = pt - m_B;
	GLvec3f ba = m_A - m_B;
	if( bx.Distance( ba ) <0.f )
		return false;

	ab.Normalize();
	ab.Scale( ax.DotProd( ab ) );
	
	GLvec3f c = m_A + ab;

	if( pt.Distance(c) > epsilon )
		return false;

	return true;
}